package com.lvtu.monitor.shiro.service.impl;

import com.lvtu.monitor.shiro.dao.ResourceDao;
import com.lvtu.monitor.shiro.entity.Resource;
import com.lvtu.monitor.shiro.service.ResourceService;

import org.apache.shiro.authz.permission.WildcardPermission;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>User: Zhang Kaitao
 * <p>Date: 14-2-14
 * <p>Version: 1.0
 */
@Service

public class ResourceServiceImpl implements ResourceService {

    @Autowired
    private ResourceDao resourceDao;

    @Override
    public Resource createResource(Resource resource) {
        return resourceDao.createResource(resource);
    }

    @Override
    public Resource updateResource(Resource resource) {
        return resourceDao.updateResource(resource);
    }

    @Override
    public void deleteResource(Long resourceId) {
        resourceDao.deleteResource(resourceId);
    }

    @Override
    public Resource findOne(Long resourceId) {
        return resourceDao.findOne(resourceId);
    }

    @Override
    public List<Resource> findAll() {
        return resourceDao.findAll();
    }

    @Override
    public Set<String> findPermissions(Set<Long> resourceIds) {
        Set<String> permissions = new HashSet<String>();
        for(Long resourceId : resourceIds) {
            Resource resource = findOne(resourceId);
            if(resource != null && !StringUtils.isEmpty(resource.getPermission())) {
                permissions.add(resource.getPermission());
            }
        }
        return permissions;
    }

    @Override
    public List<Resource> findMenus(Set<String> permissions) {
        List<Resource> allResources = findAll();
        List<Resource> menus = new ArrayList<Resource>();
        for(Resource resource : allResources) {
            if(resource.isRootNode()) {
                continue;
            }
            if(resource.getType() != Resource.ResourceType.menu) {
                continue;
            }
            if(!hasPermission(permissions, resource)) {
                continue;
            }
            menus.add(resource);
        }
        return menus;
    }
    
    @Override
    public List<Resource> getCascadeMenus(List<Resource> menus) {
    	
    	if (menus.isEmpty()) {
    		return menus;
    	}
    	
    	// 按ID排序
		Collections.sort(menus, new Comparator<Resource>() {

			@Override
			public int compare(Resource o1, Resource o2) {
				return o1.getId().compareTo(o2.getId());
			}
		});
    	
    	List<Resource> firstMenus = new ArrayList<Resource>();
    	List<Resource> secondMenus = new ArrayList<Resource>();
    	
    	// 区分一级和二级菜单
    	for (Resource menu : menus) {
    		if (menu.getLevel() == 1) {
    			firstMenus.add(menu);
    		} else if (menu.getLevel() == 2) {
    			secondMenus.add(menu);
    		}
    	}
    	
    	// 建立级联关系
    	for (Resource firstMenu : firstMenus) {
    		List<Resource> subMenus = new ArrayList<Resource>();
    		for (Resource secondMenu : secondMenus) {
    			if (secondMenu.getParentId() == firstMenu.getId()) {
    				subMenus.add(secondMenu);
    			}
    		}
    		firstMenu.setSubResources(subMenus);
    	}
    	
    	return firstMenus;
    }

	private boolean hasPermission(Set<String> permissions, Resource resource) {
        if(StringUtils.isEmpty(resource.getPermission())) {
            return true;
        }
        for(String permission : permissions) {
            WildcardPermission p1 = new WildcardPermission(permission);
            WildcardPermission p2 = new WildcardPermission(resource.getPermission());
            if(p1.implies(p2) || p2.implies(p1)) {
                return true;
            }
        }
        return false;
    }
}
